import React from 'react'
import SignaturePadLib from 'signature_pad'
import { Icon, Button } from "antd"

import { Subject  } from 'rxjs'
import { debounceTime, throttleTime, bufferTime, bufferWhen } from 'rxjs/operators'
import { MyIcon } from "../my-icon/index"

import style from './index.less'

//获取旋转后的canvas
function getRoundedCanvas (sourceCanvas, rotate) {
    let roundedCanvas = document.createElement("canvas")
    document.body.appendChild(roundedCanvas);
    let sourceCanvasWidth = sourceCanvas.width
    let sourceCanvasHeight = sourceCanvas.height

    let sin = Math.abs(Math.sin(rotate))
    let cos = Math.abs(Math.cos(rotate))

    let roundedCanvasHeight = sourceCanvasWidth * sin + sourceCanvasHeight * cos
    let roundedCanvasWidth = sourceCanvasWidth * cos + sourceCanvasHeight * sin

    roundedCanvas.width = roundedCanvasWidth
    roundedCanvas.height = roundedCanvasHeight


    let ctx = roundedCanvas.getContext("2d")

    ctx.translate(roundedCanvasWidth / 2, roundedCanvasHeight / 2)
    ctx.rotate(rotate)
    ctx.drawImage(sourceCanvas, -sourceCanvas.width / 2, -sourceCanvas.height / 2)
    document.body.removeChild(roundedCanvas)

    return roundedCanvas
}

//获取裁减空白边框后的canvas
function cutCanvasEmpty (canvas) {
    let width = canvas.width
    let height = canvas.height
    let myImageData = canvas.getContext("2d").getImageData(0, 0, width, height)
    let minX = width
    let maxX = 0
    let minY = height
    let maxY = 0

    for (let i = 0; i < height; i++) {
        for (let j = 0; j < width; j++) {
            let rgb = i * width * 4 + j * 4
            let r = myImageData.data[rgb]
            let g = myImageData.data[rgb + 1]
            let b = myImageData.data[rgb + 2]
            let a = myImageData.data[rgb + 3]
            if (r !== 0 || g !== 0 || b !== 0 || a !== 0) {
                maxY = Math.max(i, maxY)
                maxX = Math.max(j, maxX)
                minY = Math.min(i, minY)
                minX = Math.min(j, minX)
            }
        }
    }
    let cutCanvas = document.createElement("canvas")
    cutCanvas.width = maxX - minX + 1
    cutCanvas.height = maxY - minY + 1
    cutCanvas.getContext("2d").drawImage(canvas, minX, minY, cutCanvas.width, cutCanvas.height, 0, 0, cutCanvas.width, cutCanvas.height)
    return cutCanvas
}


class SignaturePad extends React.Component {
    constructor (props) {
        super(props)

        this.colors = ["#111F2C", "#0089FF", "#F25643"]
        this.state = {
            vertical: true, //是否是竖屏
            activeColor: this.colors[0], //当前选中的颜色
            screenMax: 0, //工具栏的宽度，最快的文档尺寸
            infoTextVisable: true, //是否展示在这签署的提示
        }

        this.containerRef = React.createRef()
        this.root = document.body
        this.parentNode = null

        this.canvasRef = React.createRef()
    }

    shouldComponentUpdate(nextProps, nextState){
        let props = this.props
        let state = this.state
        if(props.isOpen !== nextProps.isOpen){
            this.onResize()
        }

        if(state.vertical !== nextState.vertical){
            this.onResize()
        }

        if(state.screenMax !== nextState.screenMax){
            this.onResize()
        }

        return true
    }

    componentDidMount () {
        this.parentNode = this.containerRef.current.parentElement
        this.parentNode.removeChild(this.containerRef.current)
        this.root.appendChild(this.containerRef.current)

        const canvas = this.canvasRef.current
        this.signaturePad = new SignaturePadLib(canvas)
        this.signaturePad.penColor = this.state.activeColor
        this.resizeCanvas()
        this.onResize()

        window.addEventListener("resize", this.onResize)
    }

    componentWillUnmount () {
        this.root.removeChild(this.containerRef.current)
        this.parentNode.appendChild(this.containerRef.current)

        window.removeEventListener("resize", this.onResize)
    }

    resizeCanvas = () => {
        const canvas = this.canvasRef.current
        if (!canvas) return

        let screenWidth = document.documentElement.clientWidth
        let screenHeight = document.documentElement.clientHeight
        let screenMax = Math.max(screenWidth, screenHeight)

        if(screenHeight > screenWidth){
            this.setState({
                vertical: true,
                screenMax,
                infoTextVisable: true
            })
        } else {
            this.setState({
                vertical: false,
                screenMax,
                infoTextVisable: true
            })
        }

        const ratio = Math.max(window.devicePixelRatio || 1, 1)
        canvas.width = canvas.offsetWidth * ratio
        canvas.height = canvas.offsetHeight * ratio
        canvas.getContext('2d').scale(ratio, ratio)

        const maxSize = Math.max(screenWidth, screenHeight)
        const scale = Math.max(maxSize / 600, 1.3)
        this.signaturePad.minWidth = 2 * scale
        this.signaturePad.maxWidth = 4 * scale
    }

    onResize = (() => {
        let subject = new Subject()

        // 兼容微信浏览器，旋转时，canvas尺寸没有及时更新的问题,同时避免同时缩放多次
        subject.pipe(debounceTime(1000 / 30)).subscribe(this.resizeCanvas)

        return () => {
            subject.next()
        }
    })()

    onClickConfirm = () => {
        let canvas = this.canvasRef.current
        let screenWidth = document.documentElement.clientWidth
        let screenHeight = document.documentElement.clientHeight

        let imageData
        if(screenWidth < screenHeight){
            imageData = cutCanvasEmpty(getRoundedCanvas(canvas, -90 * Math.PI / 180)).toDataURL()
        } else {
            imageData = cutCanvasEmpty(canvas).toDataURL()
        }

        this.props.onConfirm && this.props.onConfirm({
            imageData
        })
      const {openSignaturePop}=this.props
      if(openSignaturePop){
      openSignaturePop({openTab:'WRITE_SIGN'})
      }
    }

    onClickCancel = () => {
        this.props.onCancel && this.props.onCancel()
    }

    onClickClearBtn = () => {
        this.signaturePad.clear()
    }

    onSelectPenColor = (color) => {
        this.signaturePad.penColor = color
        this.setState({
            activeColor: color
        })
    }

    render () {
        let colors = this.colors
        let verticalClassName = this.state.vertical ? style.vertical : style.horizontal
        let widthStyle = {width: this.state.screenMax + "px"}

        return (
            <div className={style.padContainer} ref={this.containerRef} style={{ display: this.props.isOpen ? 'block' : 'none' }}>
                <div className={style.headerContainer + " "+ verticalClassName} style={widthStyle}>
                    <div className={style.leftContainer} onClick={this.onClickCancel}>
                        <Icon type="left" className={style.icon}></Icon>
                        返回
                    </div>
                    <div className={style.title}>
                        签名页面
                    </div>
                    <div className={style.placeHolder}>&nbsp;</div>
                </div>
                <div className={style.signatureBody + " "+ verticalClassName}>
                    {this.state.infoTextVisable && <div className={style.signHearText}>在此签名</div>}
                    <canvas ref={this.canvasRef} className={style.contentCanvas} onTouchStart={_ => this.setState({infoTextVisable: false})} />
                </div>
                <div className={style.footerContainer + " "+ verticalClassName} style={widthStyle}>
                    <div className={style.colorsContainer}>
                        {
                            colors.map((color,index) => {
                                return (
                                    <div key={index} className={style.colorItem} style={{background: color}} onClick={e => this.onSelectPenColor(color)}>
                                        {
                                            this.state.activeColor === color && <MyIcon className={style.icon} type="icongou" />
                                        }
                                    </div>
                                )
                            })
                        }
                    </div>
                    <div className={style.btnsContainer}>
                        <Button className={style.btn} type="default" shape="round" onClick={this.onClickClearBtn}>重写</Button>
                        <Button className={style.btn} type="primary" shape="round" onClick={this.onClickConfirm}>完成</Button>
                    </div>
                </div>
            </div>
        )
    }
}

export { SignaturePad }
